/////////////////////////////////////////////////////////////////////////
// MIT License
//
// Copyright (c) 2000-2011 OpenNETCF Consulting, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
////////////////////////////////////////////////////////////////////////

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

using OpenNETCF.Windows.Forms;

namespace OpenNETCF.Windows.Forms.Calendar
{
    /// <summary>
    /// Class implements new painting logic primarly for next/prev and today buttons for calendar.  Button2 distorted VGA iamges
    /// </summary>
    internal class CalendarButton : OpenNETCF.Windows.Forms.Button2
    {
        Graphics graphicsBuffer;
        Bitmap bitmapBuffer;

        protected override void OnResize(EventArgs e)
        {
            if (this.graphicsBuffer != null)
                this.graphicsBuffer.Dispose();
            if (this.bitmapBuffer != null)
                this.bitmapBuffer.Dispose();

            this.bitmapBuffer = new Bitmap(this.Width, this.Height);
            this.graphicsBuffer = Graphics.FromImage(this.bitmapBuffer);
        }
        /// <summary>
        /// Override the paint implementation to support the VGA graphics
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            if (this.graphicsBuffer == null)
                return;

            //P{aint the background
            using (SolidBrush backColorBrush = new SolidBrush(this.BackColor))
            {
                if (this.Active)
                {
                    backColorBrush.Color = this.ActiveBackColor;
                }
                else if (!this.Enabled)
                {
                    backColorBrush.Color = this.DisabledBackColor;
                }
                this.graphicsBuffer.FillRectangle(backColorBrush, 0, 0, this.Width, this.Height);
            }

            #region Border ===========================================================================

            Size focusBorderSize = new Size(1,1);
            bool paintFocusBorder = false;
            Pen borderPen = new Pen(this.BorderColor, 1);
            Size borderOffsetSize = new Size(0, 0);
            int rectWidth = (int)borderPen.Width;
            int penOffset = (rectWidth / 2);

            // Determine the color to be used as the border for the control.
            if (this.Active)
            {
                borderPen.Color = this.ActiveBorderColor;
            }
            else if (!this.Enabled)
            {
                borderPen.Color = this.DisabledBorderColor;
            }

            // If the control is focused or specified as the default, indicate that the focus border 
            // should be painted.
            if ((this.Focused) || (this.IsDefault))
            {
                paintFocusBorder = true;
            }

            // Modify the border offset size if the focus border is to be painted.
            if (paintFocusBorder)
            {
                borderOffsetSize = focusBorderSize;
            }

            // Paint the border for the control.
            switch (this.BorderStyle)
            {
                case BorderStyle.FixedSingle:
                    {
                        // Paint the border for the control with a single-line appearance.
                        this.graphicsBuffer.DrawRectangle(borderPen, (borderOffsetSize.Width + penOffset), (borderOffsetSize.Height + penOffset), (this.ClientRectangle.Width - (borderOffsetSize.Width * 2) - (penOffset * 2) - 1), (this.ClientRectangle.Height - (borderOffsetSize.Height * 2) - (penOffset * 2) - 1));
                        break;
                    }
                case BorderStyle.Fixed3D:
                    {
                        // TODO: Ensure that the fixed 3D border can scale on higher DPI platforms.

                        // TODO: If the control is focused and the BorderStyle property is set to Fixed3D, a dotted 
                        // rectangle should be painted around the outside of the content rectangle.

                        // TODO: Calculate the light and dark border colors based on the painted background color.

                        Color darkBorderColor = SystemColors.ControlDark;
                        Color darkestBorderColor = Color.Black;
                        Color lightBorderColor = SystemColors.Control;
                        Color lightestBorderColor = SystemColors.ControlLightLight;
                        Pen borderPenFixed3D = new Pen(darkBorderColor);

                        // Paint the border for the control with a three-dimensional appearance. The border 
                        // will look different depending on whether the control is in an active or inactive 
                        // state.
                        if (!this.Active)
                        {
                            // Paint the dark lines.
                            this.graphicsBuffer.DrawLine(borderPenFixed3D, (this.ClientRectangle.Width - borderOffsetSize.Width - 2), (borderOffsetSize.Height + 1), (this.ClientRectangle.Width - borderOffsetSize.Width - 2), (this.ClientRectangle.Height - borderOffsetSize.Height - 2));
                            this.graphicsBuffer.DrawLine(borderPenFixed3D, (borderOffsetSize.Width + 1), (this.ClientRectangle.Height - borderOffsetSize.Height - 2), (this.ClientRectangle.Width - borderOffsetSize.Width - 2), (this.ClientRectangle.Height - borderOffsetSize.Height - 2));
                            // Paint the darkest lines.
                            borderPenFixed3D.Color = darkestBorderColor;
                            this.graphicsBuffer.DrawLine(borderPenFixed3D, (this.ClientRectangle.Width - borderOffsetSize.Width - 1), borderOffsetSize.Height, (this.ClientRectangle.Width - borderOffsetSize.Width - 1), (this.ClientRectangle.Height - borderOffsetSize.Height - 1));
                            this.graphicsBuffer.DrawLine(borderPenFixed3D, borderOffsetSize.Width, (this.ClientRectangle.Height - borderOffsetSize.Height - 1), (this.ClientRectangle.Width - borderOffsetSize.Width - 1), (this.ClientRectangle.Height - borderOffsetSize.Height - 1));
                            // Paint the light lines.
                            borderPenFixed3D.Color = lightBorderColor;
                            this.graphicsBuffer.DrawLine(borderPenFixed3D, (borderOffsetSize.Width + 1), (borderOffsetSize.Height + 1), (this.ClientRectangle.Width - borderOffsetSize.Width - 3), (borderOffsetSize.Height + 1));
                            this.graphicsBuffer.DrawLine(borderPenFixed3D, (borderOffsetSize.Width + 1), (borderOffsetSize.Height + 1), (borderOffsetSize.Width + 1), (this.ClientRectangle.Height - borderOffsetSize.Height - 3));
                            // Paint the lightest lines.
                            borderPenFixed3D.Color = lightestBorderColor;
                            this.graphicsBuffer.DrawLine(borderPenFixed3D, borderOffsetSize.Width, borderOffsetSize.Height, (this.ClientRectangle.Width - borderOffsetSize.Width - 2), borderOffsetSize.Height);
                            this.graphicsBuffer.DrawLine(borderPenFixed3D, borderOffsetSize.Width, borderOffsetSize.Height, borderOffsetSize.Width, (this.ClientRectangle.Height - borderOffsetSize.Height - 2));
                        }
                        else
                        {
                            this.graphicsBuffer.DrawRectangle(borderPenFixed3D, borderOffsetSize.Width, borderOffsetSize.Height, (this.ClientRectangle.Width - (borderOffsetSize.Width * 2) - 1), (this.ClientRectangle.Height - (borderOffsetSize.Height * 2) - 1));
                        }

                        // Release any resources.
                        borderPenFixed3D.Dispose();

                        break;
                    }
            }

            // If the control is focused or specified as the default, paint a focus border.
            if (paintFocusBorder)
            {
                this.graphicsBuffer.DrawRectangle(borderPen, penOffset, penOffset, (this.ClientRectangle.Width - (penOffset * 2) - 1), (this.ClientRectangle.Height - (penOffset * 2) - 1));
            }

            // Release any resources.
            borderPen.Dispose();

            #endregion ===============================================================================

            if (this.Image != null)
            {
                //Since this is a calendar button basically used for the left/right and today buttons we
                //will just draw the image centered within the button
                //Draw the image
                Point pt = new Point();
                pt.X = this.Width / 2 - this.Image.Width / 2;
                pt.Y = this.Height / 2 - this.Image.Height / 2;

                //Draw the image using transparency
                ImageAttributes attributes = new ImageAttributes();
                
                // Get the color of the top-left pixel in the content image.
                using(Bitmap b = new Bitmap(this.Image))
                    attributes.SetColorKey(b.GetPixel(0, 0), b.GetPixel(0, 0));

                //Draw the image
                this.graphicsBuffer.DrawImage(this.Image, new Rectangle(pt.X,pt.Y,this.Image.Width,this.Image.Height), 0, 0, this.Image.Width, this.Image.Height, GraphicsUnit.Pixel, attributes);
            }

            //blit
            e.Graphics.DrawImage(this.bitmapBuffer, 0, 0);
        }
    }
}
